// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use pyo3::{buffer, prelude::*};
use std::env;
use pyo3::types::PyTuple;
use rfd::FileDialog;
use pyo3::types::PyList;
use std::fs;
use std::path::Path;
use std::io::Write;
use std::fs::File;


fn main() {
   // 设置PYTHONPATH来包含虚拟环境中的site-packages目录
   let python_path = "./python/Lib/site-packages";
   env::set_var("PYTHONPATH", &python_path);
   // 设置PYTHONEXECUTABLE来指向虚拟环境中的Python解释器
   let python_executable = "./python/python.exe";
   env::set_var("PYTHONEXECUTABLE", &python_executable);
   // 初始化Python解释器，确保可以使用Python API
   pyo3::prepare_freethreaded_python();
   tauri::Builder::default()
   .invoke_handler(tauri::generate_handler![template_txt,template_json_py,data_py,save_json])
   .run(tauri::generate_context!())
   .expect("error while running tauri application");
}

#[tauri::command]
fn template_txt()->String {
   let buffer= fs::read_to_string("./test.txt").unwrap();
   buffer
}


fn call_python_function() -> Result<Py<PyAny>,PyErr> {
    
    let path = Path::new(r"./python_scripts"); // 相对路径的python_app目录,也可使用绝对路径：D:/rust/rust_py/python_app
    // 读取app.py文件的内容为字符串
    let py_app = fs::read_to_string(path.join("app.py")).expect("Failed to read app.py");
    
    // 使用Python全局解释器锁执行Python代码
    let from_python = Python::with_gil(|py| -> PyResult<Py<PyAny>> {
        let syspath = py
            .import_bound("sys")? // 获取sys模块
            .getattr("path")?  // 获取sys.path列表
            .downcast_into::<PyList>()?; // 转换为PyList类型
        syspath.insert(0, &path)?; // 在sys.path列表的开头插入python_app目录
        
        // 将app.py的内容作为一个Python模块加载，并获取其中的"run"属性
        let app: Py<PyAny> = PyModule::from_code_bound(py, &py_app, "", "")?
            .getattr("function3")?
            .into();
         // 调用"run"函数，传入文件路径作为参数
        //  let args = PyTuple::new_bound(py, &[filepath]);
        app.call0(py)
    });

    from_python

}

#[tauri::command]
fn data_py() -> String {
    match call_python_function() {
        Ok(result) => {
            result.to_string()
        },
        Err(e) => {
            println!("py error: {}", e);
            "Error".to_string()
        }
    }
}


#[tauri::command]
fn template_json_py() -> String {
    match call_python_function() {
        Ok(result) => {
            result.to_string()
        },
        Err(e) => {
            println!("py error: {}", e);
            "Error".to_string()
        }
    }
}


// 选择文件路径
fn _get_filepath()->Result<String,std::io::Error> {
    let file = FileDialog::new()
        .add_filter("Text Files", &["xlsx"])
        .pick_file();

    match file {
        Some(path) => Ok(path.to_str().unwrap().to_string()),
        None => Err(std::io::Error::new(std::io::ErrorKind::Other, "No file selected"))
    }
}

// 接收一个模板json字符串，并将其保存到文件中
#[tauri::command]
fn save_json(json_str: String) -> Result<String, String> {
    let path = Path::new("./test.txt");
    let mut file = File::create(&path).map_err(|e| format!("Failed to create file: {}", e))?;
    file.write_all(json_str.as_bytes()).map_err(|e| format!("Failed to write to file: {}", e))?;
    Ok("success".to_string())
}